﻿#region Copyrights Notice
//©2010 Microsoft Corporation. All rights reserved.
#endregion

#region usings
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;
using System.Configuration;
using System.Collections;
using System.Reflection;
using System.Diagnostics;
using System.Xml.XPath;
#endregion

namespace Microsoft.InformationSecurity.CISF.Common.Utilities
{
    public enum ConfigFileType
    {
        WebConfig,
        AppConfig
    }

    public class WebConfigManager : System.Configuration.AppSettingsReader
    {
        public string docName = String.Empty;
        private XmlNode node = null;
        private int _configType;

        public int ConfigType
        {
            get
            {
                return _configType;
            }
            set
            {
                _configType = value;
           }
        }
        public string getValue(string selectednode, string key)
        {
            string value = string.Empty;

            return value;
        }

        public string getPrivatePathValue(string key)
        {
            string value = string.Empty;
            XmlDocument cfgDoc = new XmlDocument();
            XmlDocument cfgDoc1 = new XmlDocument(); 
            loadConfigDoc(cfgDoc);

            //set the navigator
            XPathNavigator navigator = cfgDoc.CreateNavigator();

            XmlNamespaceManager manager = new XmlNamespaceManager(navigator.NameTable);
            manager.AddNamespace("ab", "urn:schemas-microsoft-com:asm.v1");

            // retrieve the selected node 
            XPathNavigator node = navigator.SelectSingleNode("//ab:assemblyBinding", manager);

            if (node == null)
            {
                throw new System.InvalidOperationException("selected node not found");
            }
            //else continue
            try
            {
                XPathNavigator nav1 = node.SelectSingleNode("//ab:assemblyBinding", manager);
                // XPath select probing path element that contains the path
                cfgDoc1.LoadXml(nav1.OuterXml);
                XmlNode onode = cfgDoc1.SelectSingleNode("//ab:probing", manager);
                XmlElement addElem = (XmlElement)onode.SelectSingleNode("//ab:probing", manager);
                if (addElem != null)
                {
                    value = addElem.GetAttribute("privatePath");
                } 
                return value;
            }
            catch
            {
                return null;
            }
        }

        public bool setPrivatePathValue(string value)
        {
            //set the privatePath value
            string privatePath = "Applications/" + value +"/bin";

            XmlDocument cfgDoc = new XmlDocument();
            loadConfigDoc(cfgDoc);

            //set the navigator
            XPathNavigator navigator = cfgDoc.CreateNavigator();

            XmlNamespaceManager manager = new XmlNamespaceManager(navigator.NameTable);
            manager.AddNamespace("ab", "urn:schemas-microsoft-com:asm.v1");

            // retrieve the selected node 
            XPathNavigator node = navigator.SelectSingleNode("//ab:assemblyBinding", manager);

            if (node == null)
            {
                throw new System.InvalidOperationException("selected node not found");
            }
            //else continue
            try
            {
                XPathNavigator nav1 = node.SelectSingleNode("//ab:assemblyBinding", manager);
                // XPath select probing path element that contains the path
                XmlNode onode = cfgDoc.SelectSingleNode("//ab:probing", manager);
                XmlElement addElem = (XmlElement)onode.SelectSingleNode("//ab:probing", manager);
                if (addElem != null)
                {
                    string currPrivatePath = addElem.GetAttribute("privatePath");
                    if (currPrivatePath =="")
                        addElem.SetAttribute("privatePath", privatePath);
                    else
                        addElem.SetAttribute("privatePath", currPrivatePath + ";" + privatePath);
                }
                //save it
                saveConfigDoc(cfgDoc, docName);
                return true;
            }
            catch
            {
                return false;
            }
        }

        public bool removePrivatePathValue(string value)
        {
            //set the privatePath value
            string privatePath = "Applications/" + value + "/bin";

            XmlDocument cfgDoc = new XmlDocument();
            loadConfigDoc(cfgDoc);

            //set the navigator
            XPathNavigator navigator = cfgDoc.CreateNavigator();

            XmlNamespaceManager manager = new XmlNamespaceManager(navigator.NameTable);
            manager.AddNamespace("ab", "urn:schemas-microsoft-com:asm.v1");

            // retrieve the selected node 
            XPathNavigator node = navigator.SelectSingleNode("//ab:assemblyBinding", manager);

            if (node == null)
            {
                throw new System.InvalidOperationException("selected node not found");
            }
            //else continue
            try
            {
                XPathNavigator nav1 = node.SelectSingleNode("//ab:assemblyBinding", manager);
                // XPath select probing path element that contains the path
                XmlNode onode = cfgDoc.SelectSingleNode("//ab:probing", manager);
                XmlElement addElem = (XmlElement)onode.SelectSingleNode("//ab:probing", manager);
                if (addElem != null)
                {
                    string currPrivatePath = addElem.GetAttribute("privatePath");

                    //remove the privatePath attribute
                    addElem.RemoveAttribute("privatePath");

                    string[] Split = currPrivatePath.Split(new Char[] { ';' });
                    foreach (string s in Split)
                    {
                        if (s != privatePath)
                        {
                            string currs = addElem.GetAttribute("privatePath");
                            if (currs == "")
                                addElem.SetAttribute("privatePath", s);
                            else
                                addElem.SetAttribute("privatePath", currs + ";" + s);
                        }
                    }
                    //save it
                    saveConfigDoc(cfgDoc, docName);
                    return true;
                }
                else
                    return false;
            }
            catch
            {
                return false;
            }
        }

        public bool SetValue(string selectednode, string key, string value)
        {
            XmlDocument cfgDoc = new XmlDocument();
            loadConfigDoc(cfgDoc);
            // retrieve the appSettings node 
            node = cfgDoc.SelectSingleNode("//" + selectednode);

            if (node == null)
            {
                throw new System.InvalidOperationException("Selected node not found");
            }

            try
            {
                // XPath select setting "add" element that contains this key    
                XmlElement addElem = (XmlElement)node.SelectSingleNode("//add[@key='" + key + "']");
                if (addElem != null)
                {
                    addElem.SetAttribute("value", value);
                }
                // not found, so we need to add the element, key and value
                else
                {
                    XmlElement entry = cfgDoc.CreateElement("add");
                    entry.SetAttribute("key", key);
                    entry.SetAttribute("value", value);
                    node.AppendChild(entry);
                }
                //save it
                saveConfigDoc(cfgDoc, docName);
                return true;
            }
            catch
            {
                return false;
            }
        }

        private void saveConfigDoc(XmlDocument cfgDoc, string cfgDocPath)
        {
            try
            {
                XmlTextWriter writer = new XmlTextWriter(cfgDocPath, null);
                writer.Formatting = Formatting.Indented;
                cfgDoc.WriteTo(writer);
                writer.Flush();
                writer.Close();
                return;
            }
            catch
            {
                throw;
            }
        }

        public bool removeElement(string elementKey)
        {
            try
            {
                XmlDocument cfgDoc = new XmlDocument();
                loadConfigDoc(cfgDoc);
                // retrieve the appSettings node 
                node = cfgDoc.SelectSingleNode("//appSettings");
                if (node == null)
                {
                    throw new System.InvalidOperationException("appSettings section not found");
                }
                // XPath select setting "add" element that contains this key to remove   
                node.RemoveChild(node.SelectSingleNode("//add[@key='" + elementKey + "']"));

                saveConfigDoc(cfgDoc, docName);
                return true;
            }
            catch
            {
                return false;
            }
        }

        private XmlDocument loadConfigDoc(XmlDocument cfgDoc)
        {
            // load the config file if value does not exist
            if (string.IsNullOrEmpty(docName))
            {
                if (Convert.ToInt32(ConfigType) == Convert.ToInt32(ConfigFileType.AppConfig))
                {

                    docName = ((Assembly.GetEntryAssembly()).GetName()).Name;
                    docName += ".exe.config";
                }
                else
                {
                    docName = System.Web.HttpContext.Current.Server.MapPath("~//web.config");
                    //docName = "D:\\SecurityPortal\\applications\\SampleApp\\web.config";
                }
            }
            cfgDoc.Load(docName);
            return cfgDoc;
        }
    }
}
